import logging
import time

import colorlog

from common import constants
from common.util import Util


class LoggerHandler:
    """
    如果使用日志输出到控制台，可能会出现日志的输出延迟于print或者input函数；使用时请注意主动停顿来保证顺序
    """

    __file_handler = None
    __console_handler = None

    '''
    终端输出日志颜色配置
    '''
    __log_colors_config = {
        'DEBUG': 'white',
        'INFO': 'cyan',
        'WARNING': 'yellow',
        'ERROR': 'red',
        'CRITICAL': 'bold_red',
    }

    __def_formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
    __color_formatter = colorlog.ColoredFormatter(
        '%(log_color)s%(asctime)s - %(levelname)s - %(message)s%(reset)s',
        datefmt=constants.DATE_TIME_FORMAT, reset=True, log_colors=__log_colors_config)

    @classmethod
    def get_file_handler(cls):
        # 保证文件处理器全局仅创建一次
        if cls.__file_handler is None:
            cls.__file_handler = cls._create_file_handler()
        current_date = time.strftime(constants.DATE_FORMAT, time.localtime())
        # 每日创建一个文件
        if current_date not in cls.__file_handler.baseFilename:
            cls.__file_handler.flush()
            cls.__file_handler.close()
            cls.__file_handler = cls._create_file_handler()
        return cls.__file_handler

    @classmethod
    def get_console_handler(cls):
        if cls.__console_handler is None:
            cls.__console_handler = cls._create_console_handler()
        return cls.__console_handler

    @staticmethod
    def _create_file_handler():
        current_date = time.strftime(constants.DATE_FORMAT, time.localtime())
        log_filename = f"{Util.unified_static_path(constants.LOG_SAVE_DIRECTORY)}/{current_date}.log"
        file_handler = logging.FileHandler(log_filename, encoding='utf-8')
        file_handler.setFormatter(LoggerHandler.__def_formatter)
        return file_handler

    @staticmethod
    def _create_console_handler():
        console_handler = colorlog.StreamHandler()
        console_handler.setFormatter(LoggerHandler.__color_formatter)
        return console_handler


class Log:

    @classmethod
    def file(cls):
        logger = logging.getLogger('file_logger')
        logger.setLevel(logging.DEBUG)
        # 移除旧的FileHandler，防止新日志往旧文件输出
        for handler in logger.handlers:
            if isinstance(handler, logging.FileHandler):
                logger.removeHandler(handler)
        logger.addHandler(LoggerHandler.get_file_handler())
        return logger

    @classmethod
    def console(cls):
        logger = logging.getLogger('console_logger')
        logger.setLevel(logging.DEBUG)
        logger.addHandler(LoggerHandler.get_console_handler())
        return logger

    @classmethod
    def debug(cls, message):
        file_logger = cls.file()
        console_logger = cls.console()
        file_logger.debug(message)
        console_logger.debug(message)

    @classmethod
    def info(cls, message):
        file_logger = cls.file()
        console_logger = cls.console()
        file_logger.info(message)
        console_logger.info(message)

    @classmethod
    def warning(cls, message):
        file_logger = cls.file()
        console_logger = cls.console()
        file_logger.warning(message)
        console_logger.warning(message)

    @classmethod
    def error(cls, message):
        file_logger = cls.file()
        console_logger = cls.console()
        file_logger.error(message)
        console_logger.error(message)
